#include "stdafx.h"
#include "dbg_log_output.h"

#define _NO_DBG_LOG_WRITE_FILE

#define MAX_LOG_BUF_SIZE 131072
char log_file[256];
char* log_buf;
int log_buf_size;
CRITICAL_SECTION cs;
HANDLE hFile;

extern HMODULE hInstance;

void FinishDbgSaveToFile()
{
#ifndef _NO_DBG_LOG_WRITE_FILE
	EnterCriticalSection(&cs);
	if (log_buf_size > 0)
	{
		SetFilePointer(hFile,GetFileSize(hFile,NULL),NULL,FILE_BEGIN);
		WriteFile(hFile,log_buf,log_buf_size,NULL,NULL);
		FlushFileBuffers(hFile);
		CloseHandle(hFile);
		log_buf_size = 0;
	}
	OutputDebugStringA("Dbg Print Save to File.");
	LeaveCriticalSection(&cs);
#endif
}

void WriteDbgPrintToFile(char* sz)
{
#ifndef _NO_DBG_LOG_WRITE_FILE
	char buffer[128] = {0};
	if (log_buf == NULL)
	{
		log_buf = (char*)calloc(MAX_LOG_BUF_SIZE,1);
		GetModuleFileNameA(hInstance,log_file,ARRAYSIZE(log_file));
		PathRenameExtensionA(log_file,".log");
		DeleteFileA(log_file);
		hFile = CreateFileA(log_file,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,0,NULL);
		InitializeCriticalSection(&cs);
		wsprintfA(buffer,"log_buffer_memory:0x%08X",log_buf);
		OutputDebugStringA(buffer);
	}
	int len = strlen(sz);
	if ((log_buf_size + len) < (MAX_LOG_BUF_SIZE - 16))
	{
		SYSTEMTIME st = {0};
		GetLocalTime(&st);
		wsprintfA(buffer,"[%02d-%02d-%02d:%d] ",st.wHour,st.wMinute,st.wSecond,st.wMilliseconds);
		EnterCriticalSection(&cs);
		log_buf_size = log_buf_size + len + 2 + strlen(buffer);
		strcat(log_buf,buffer);
		strcat(log_buf,sz);
		strcat(log_buf,"\r\n");
		LeaveCriticalSection(&cs);
	}else{
		EnterCriticalSection(&cs);
		if (hFile != INVALID_HANDLE_VALUE)
		{
			SetFilePointer(hFile,GetFileSize(hFile,NULL),NULL,FILE_BEGIN);
			WriteFile(hFile,log_buf,log_buf_size,NULL,NULL);
			FlushFileBuffers(hFile);
			CloseHandle(hFile);
			hFile = CreateFileA(log_file,GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
		}
		log_buf_size = len + 2;
		memset(log_buf,0,MAX_LOG_BUF_SIZE);
		strcpy(log_buf,sz);
		strcat(log_buf,"\r\n");
		LeaveCriticalSection(&cs);
	}
#endif
}

void __cdecl LogDbgPrint(char* psz,...)
{
#ifndef _NO_DBG_LOG_PRINT
	if (psz == NULL)
		return;
	va_list args;
	va_start(args,psz);
	char sz[1024];
	vsnprintf(sz,1024,psz,args);
#ifdef _NO_DBG_LOG_WRITE_FILE
	OutputDebugStringA(sz);
#endif
	WriteDbgPrintToFile(sz);
	va_end(args);
#endif
}

void __cdecl LogDbgPrintForce(wchar_t* psz,...)
{
#ifndef _NO_DBG_LOG_PRINT_FORCE
	va_list args;
	va_start(args,psz);
	wchar_t sz[1024];
	_vsnwprintf(sz,1024,psz,args);
	wcscat(sz,L"\n");
	OutputDebugStringW(sz);
	va_end(args);
#endif
}

void LogDbgPrintQI(REFIID riid)
{
#ifndef _NO_DBG_LOG_PRINT
	LPOLESTR lp = NULL;
	StringFromIID(riid,&lp);
	OutputDebugStringW(lp);
	CoTaskMemFree(lp);
#endif
}

void __cdecl FFmpeg_LogPrint_Callback(void* ptr,int level,const char* fmt,va_list vl)
{
#ifndef _NO_DBG_LOG_PRINT
	char sz[1024] = {};
	strcpy(sz,"FFmpeg:");
	vsnprintf(&sz[7],1024,fmt,vl);
	OutputDebugStringA(sz);
	WriteDbgPrintToFile(sz);
#endif
}